home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / m68k / sys_call.S < prev    next >
Encoding:
Text File  |  1994-06-12  |  7.4 KB  |  318 lines

  1. /*
  2.  *  linux/kernel/sys_call.S
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  *
  10.  * 680x0 support by Hamish Macdonald
  11.  *
  12.  */
  13.  
  14. /*
  15.  * sys_call.S  contains the system-call and fault low-level handling routines.
  16.  * This also contains the timer-interrupt handler, as well as all interrupts
  17.  * and faults that can result in a task-switch.
  18.  *
  19.  * NOTE: This code handles signal-recognition, which happens every time
  20.  * after a timer-interrupt and after each system call.
  21.  *
  22.  * Stack layout in '_ret_from_exception':
  23.  *    ptrace needs to have all regs on the stack.
  24.  *    if the order here is changed, it needs to be
  25.  *    updated in fork.c:sys_fork, signal.c:do_signal,
  26.  *    ptrace.c and ptrace.h
  27.  *
  28.  *    This allows access to the syscall arguments in registers d1-d5
  29.  *
  30.  *     0(sp) - d1
  31.  *     4(sp) - d2
  32.  *     8(sp) - d3
  33.  *     C(sp) - d4
  34.  *    10(sp) - d5
  35.  *    14(sp) - d6
  36.  *    18(sp) - d7
  37.  *    1C(sp) - a0
  38.  *    20(sp) - a1
  39.  *    24(sp) - a2
  40.  *    28(sp) - a3
  41.  *    2C(sp) - a4
  42.  *    30(sp) - a5
  43.  *    34(sp) - a6
  44.  *    38(sp) - d0
  45.  *    3C(sp) - usp
  46.  *    40(sp) - orig_d0
  47.  *    44(sp) - stack adjustment
  48.  *    46(sp) - sr
  49.  *    48(sp) - pc
  50.  *    4C(sp) - format & vector
  51.  */
  52.  
  53. LOFF_D1     = 0x00
  54. LOFF_D2     = 0x04
  55. LOFF_D3     = 0x08
  56. LOFF_D4     = 0x0C
  57. LOFF_D5     = 0x10
  58. LOFF_D6     = 0x14
  59. LOFF_D7     = 0x18
  60. LOFF_A0     = 0x1C
  61. LOFF_A1     = 0x20
  62. LOFF_A2     = 0x24
  63. LOFF_A3     = 0x28
  64. LOFF_A4     = 0x2C
  65. LOFF_A5     = 0x30
  66. LOFF_A6     = 0x34
  67. LOFF_D0     = 0x38
  68. LOFF_USP    = 0x3C
  69. LOFF_ORIG_D0    = 0x40
  70. LOFF_STKADJ    = 0x44
  71. LOFF_SR     = 0x46
  72. LOFF_PC     = 0x48
  73. LOFF_FORMAT    = 0x4C
  74.  
  75.  
  76. LCF_MASK    = 0x0001
  77.  
  78. LENOSYS = 38
  79.  
  80. LESP0_OFFSET    = 2436
  81.  
  82. /*
  83.  * these are offsets into the task-struct
  84.  */
  85. LTS_STATE    =  0
  86. LTS_COUNTER    =  4
  87. LTS_PRIORITY    =  8
  88. LTS_SIGNAL    = 12
  89. LTS_BLOCKED    = 16
  90. LTS_FLAGS    = 20
  91. LTS_ERRNO    = 24
  92.  
  93. .globl _system_call, _buserr, _trap
  94. .globl _ret_from_exception, _inthandler
  95.  
  96. .text
  97. .align 4
  98. _buserr:
  99.     clrw    sp@-            | stack adjustment
  100.     subql    #8,sp            | make room for usp and orig_d0
  101.     movel    d0,sp@-
  102.     moveml    d1-a6,sp@-
  103.     movec    usp,a0
  104.     movel    a0,sp@(LOFF_USP)
  105.     moveq    #-1,d0
  106.     movel    d0,sp@(LOFF_ORIG_D0)    | a -1 in the ORIG_D0 field
  107.                     | signifies that the stack frame
  108.                     | is NOT for syscall
  109.  
  110.     | save top of frame
  111.     movel    _current,a0
  112.     movel    sp,a0@(LESP0_OFFSET)
  113.  
  114.     movel    sp,sp@-         | stack frame pointer argument
  115.     bsr    _buserr_c
  116.     addql    #4,sp
  117.     bra    _ret_from_exception
  118.  
  119. .align 4
  120. _trap:
  121.     clrw    sp@-            | stack adjustment
  122.     subql    #8,sp            | make room for usp and orig_d0
  123.     movel    d0,sp@-
  124.     moveml    d1-a6,sp@-
  125.     movec    usp,a0
  126.     movel    a0,sp@(LOFF_USP)
  127.     moveq    #-1,d0
  128.     movel    d0,sp@(LOFF_ORIG_D0)    | a -1 in the ORIG_D0 field
  129.                     | signifies that the stack frame
  130.                     | is NOT for syscall
  131.     | save top of frame
  132.     movel    _current,a0
  133.     movel    sp,a0@(LESP0_OFFSET)
  134.  
  135.     movel    sp,sp@-         | stack frame pointer argument
  136.     bsr    _trap_c
  137.     addql    #4,sp
  138.     bra    _ret_from_exception
  139. .align 4
  140. reschedule:
  141.     movel    #_ret_from_exception,sp@-
  142.     jmp    _schedule
  143.  
  144. .align 4
  145. _system_call:
  146.     clrw    sp@-            | stack adjustment
  147.     subql    #8,sp            | make room for usp and orig_d0
  148.     movel    #-LENOSYS,sp@-        | default return value in D0
  149.     moveml    d1-a6,sp@-        | save registers
  150.     movec    usp,a0
  151.     movel    a0,sp@(LOFF_USP)        | save User Stack Pointer
  152.     movel    d0,sp@(LOFF_ORIG_D0)    | save original D0 (syscall #)
  153.  
  154.     | save top of frame
  155.     movel    _current,a0
  156.     movel    sp,a0@(LESP0_OFFSET)
  157.  
  158.     cmpl    _NR_syscalls,d0
  159.     bgt    _ret_from_exception
  160.     andw    #~LCF_MASK,sp@(LOFF_SR) | assume syscall success
  161.     clrl    a0@(LTS_ERRNO)
  162.     btst    #5,a0@(LTS_FLAGS+3)     | PF_TRACESYS
  163.     bnes    1f
  164.     lea    _sys_call_table,a0
  165.     movel    a0@(d0:l:4),a0
  166.     jbsr    a0@
  167.     movel    d0,sp@(LOFF_D0)         | save the return value
  168.     bpl    2f
  169.     orw    #LCF_MASK,sp@(LOFF_SR)  | set carry to indicate error
  170. 2:
  171.     movel    _current,a0
  172.     movel    a0@(LTS_ERRNO),d1
  173.     negl    d1
  174.     beq    _ret_from_exception
  175.     movel    d1,sp@(LOFF_D0)
  176.     orw    #LCF_MASK,sp@(LOFF_SR)  | set carry to indicate error
  177.     bra    _ret_from_exception
  178. 1:    jbsr    _syscall_trace
  179.     movel    sp@(LOFF_ORIG_D0),d0
  180.     lea    _sys_call_table,a0
  181.     movel    a0@(d0:l:4),a0
  182.     jbsr    a0@
  183.     movel    d0,sp@(LOFF_D0)         | save the return value
  184.     bpl    2f
  185.     orw    #LCF_MASK,sp@(LOFF_SR)  | set carry to indicate error
  186. 2:
  187.     movel    _current,a0
  188.     movel    a0@(LTS_ERRNO),d1
  189.     negl    d1
  190.     beq    2f
  191.     movel    d1,sp@(LOFF_D0)
  192.     orw    #LCF_MASK,sp@(LOFF_SR)  | set carry to indicate error
  193. 2:    jbsr     _syscall_trace
  194.  
  195. _ret_from_exception:
  196.     btst    #5,sp@(LOFF_SR)        | check if returning to kernel
  197.     bnes    2f            | if so, skip resched, signals
  198.     tstl    _need_resched
  199.     bne    reschedule
  200.     movel    _current,a0
  201.     cmpl    #_task,a0        | task[0] cannot have signals
  202.     beq    2f
  203.     btst    #6,a0@(LTS_FLAGS+3)    | check for delayed trace
  204.     beq    1f
  205.     bclr    #6,a0@(LTS_FLAGS+3)    | clear delayed trace bit
  206.     bclr    #7,sp@(LOFF_SR)        | clear trace bit in SR
  207.     pea    1            | send SIGTRAP
  208.     movel    a0,sp@-
  209.     pea    5
  210.     jbsr    _send_sig
  211.     addql    #8,sp
  212.     addql    #4,sp
  213. 1:
  214.     moveq    #0,d0
  215.     cmpl    a0@(LTS_STATE),d0       | state
  216.     bne    reschedule
  217.     cmpl    a0@(LTS_COUNTER),d0     | counter
  218.     beq    reschedule
  219.     movel    a0@(LTS_BLOCKED),d0
  220.     movel    d0,d1            | save blocked in d1 for signal handling
  221.     notl    d0
  222.     andl    a0@(LTS_SIGNAL),d0
  223.     bne    Lsignal_return
  224. 2:    movel    sp@(LOFF_USP),a0
  225.     movec    a0,usp
  226.     moveml    sp@+,d1-a6
  227.     movel    sp@+,d0     | restore d0
  228.     addql    #8,sp        | skip the usp and orig_d0
  229.     addw    sp@+,sp     | add the stack adjustment
  230.     rte
  231. Lsignal_return:
  232.     movel    sp,sp@-
  233.     movel    d1,sp@-
  234.     bsr    _do_signal
  235.     addql    #8,sp
  236.     bras    2b
  237.  
  238.  
  239. /*
  240. ** This is the main interrupt handler, responsible for calling process_int()
  241. */
  242. _inthandler:
  243.     moveml    a0-a1/d0-d1,sp@-    |  save registers
  244.  
  245.     addql    #1,_intr_count
  246.     movew    sp@(22),d0              |  put exception # in d0
  247.     andil    #0xfff,d0        |  mask out format nybble
  248.  
  249.     subil    #0x60,d0        |  convert from vector offset...
  250.     lsrl    #2,d0            |  ...to IRQ number
  251.  
  252.     beq    Lspurious        |  if zero, spurious interrupt
  253.     pea    sp@            |  push interrupt stack frame address
  254.     movel    d0,sp@-         |  put IRQ # on stack
  255.     jbsr    _process_int        |  process the IRQ
  256.     addql    #8,sp            |  pop parameters off stack
  257.  
  258.     subql    #1,_intr_count
  259.  
  260.  
  261.     /* maybe process software interrupts */
  262.     tstl    _intr_count
  263.     bne    1f
  264.  
  265.     movel    _bh_mask,d0
  266.     andl    d0,_bh_active
  267.     beq    1f
  268.  
  269.     movew    sr,sp@-
  270.     addql    #1,_intr_count
  271.     andiw    #0xfbff,sr        | allow interrupts
  272.     jbsr    _do_bottom_half
  273.     movew    sp@+,sr
  274.     subql    #1,_intr_count
  275. 1:
  276.     /*
  277.      * check if returning to user mode.
  278.      * if so, pop stuff off interrupt stack, switch
  279.      * from interrupt mode to master mode, push
  280.      * stack frame on kernel stack and jump to ret_from_exception
  281.      */
  282.     moveb    sp@(22),d0              | get format word from int stack
  283.     andb    #0xf0,d0        | mask off format
  284.     cmpb    #0x10,d0        | check if throwaway frame
  285.     beq    Lnotstacked        | if, not: interrupts stacked, rte
  286.     moveml    sp@+,a0-a1/d0-d1    | restore registers
  287.     rte
  288. Lnotstacked:
  289.     movec    msp,a0            | get the master stack pointer
  290.     btst    #0x5,a0@        | supervisor bit set in saved SR?
  291.     moveml    sp@+,a0-a1/d0-d1    | restore registers
  292.     beq    Lnotkernel        | if in kernel, rte
  293.     rte
  294. Lnotkernel:
  295.     addql    #8,sp            | throw away throwaway stack frame
  296.     oriw    #0x1000,sr        | set master bit in SR (sp is now msp)
  297.     andiw    #0xfbff,sr        | allow interrupts
  298.     clrw    sp@-            | stack adjustment
  299.     subql    #8,sp            | make room for usp and orig_d0
  300.     moveml    d0,sp@-         | save registers as for syscall
  301.     moveml    d1-a6,sp@-
  302.     moveq    #-1,d0
  303.     movel    d0,sp@(LOFF_ORIG_D0)    | indicate stack frame not for syscall
  304.     movec    usp,a0
  305.     movel    a0,sp@(LOFF_USP)        | save usp
  306.  
  307.     | save top of frame
  308.     movel    _current,a0
  309.     movel    sp,a0@(LESP0_OFFSET)
  310.  
  311.     bra    _ret_from_exception    | deliver signals, reschedule etc..
  312. Lspurious:
  313.     addql    #1,_num_spurious    | increment the counter of spurious
  314.                     | interrupts.
  315.     subql    #1,_intr_count
  316.     moveml    sp@+,a0-a1/d0-d1    | restore registers
  317.     rte                | return from exception
  318.